﻿using System;
using System.Collections.Generic;
using System.Text;

using System.ComponentModel;
using System.Data;

using XCode;
using XCode.Attributes;
using XCode.Entity;

namespace XCMSData
{
    /// <summary>
    /// 标题
    /// </summary>
    public partial class Title : Entity
    {
        #region 事件
        #region 初始化
        /// <summary>
        /// 初始化 标题 对象时触发
        /// </summary>
        /// <param name="k">初始化位置，1是空参数，2是全参数，3是标识参数</param>
        private void OnInit(int k)
        {
        }
        #endregion

        #region 插入
        /// <summary>
        /// 插入前
        /// </summary>
        /// <returns>是否允许插入</returns>
        private static Boolean OnInserting()
        {
            return true;
        }

        /// <summary>
        /// 插入后
        /// </summary>
        /// <param name="retval">影响的行数</param>
        /// <returns>影响的行数</returns>
        private static Int32 OnInserted(Int32 retval)
        {
            hasUpdated = false;
            return retval;
        }

        /// <summary>
        /// 已重载。把该对象插入到数据库。
        /// </summary>
        /// <returns>影响的行数</returns>
        public override Int32 Insert()
        {
            if (!OnInserting()) return -1;
            return OnInserted(base.Insert());
        }
        #endregion

        #region 更新
        /// <summary>
        /// 更新前
        /// </summary>
        /// <returns>是否允许更新</returns>
        private static Boolean OnUpdating()
        {
            return true;
        }

        /// <summary>
        /// 更新后
        /// </summary>
        /// <param name="retval">影响的行数</param>
        /// <returns>影响的行数</returns>
        private static Int32 OnUpdated(Int32 retval)
        {
            hasUpdated = false;
            return retval;
        }

        /// <summary>
        /// 已重载。更新数据库。
        /// </summary>
        /// <returns>影响的行数</returns>
        public override Int32 Update()
        {
            if (!OnUpdating()) return -1;
            int retval = 0;
            //更新标题的同时，也更新文章，使用事务来保护
            try
            {
                Title.SessionDBO.BeginTransaction();

                IList<Article> list = Article.SelectAll(Article._.TitleID, ID);
                //没有则加一个
                if (list == null || list.Count < 1)
                {
                    Article a = new Article();
                    a.TitleID = this.ID;
                    a.Page = 1;
                    a.Content = this.Content;
                    a.Insert();
                }
                else
                {
                    if (list.Count != 1)
                    {
                        throw new XLog.XException("暂时不支持文章分页，请关注下一版本！");
                    }
                    list[0].Content = this.Content;
                    list[0].Update();
                }
                retval = OnUpdated(base.Update());

                Title.SessionDBO.Commit();
            }
            catch (Exception ex)
            {
                XLog.Trace.WriteLine("更新文章时出错：" + ex.Message);
                Title.SessionDBO.Rollback();
                throw;
            }
            return retval;
        }
        #endregion

        #region 删除
        /// <summary>
        /// 删除前
        /// </summary>
        /// <returns>是否允许删除</returns>
        private static Boolean OnDeleting()
        {
            return true;
        }

        /// <summary>
        /// 删除后
        /// </summary>
        /// <param name="retval">影响的行数</param>
        /// <returns>影响的行数</returns>
        private static Int32 OnDeleted(Int32 retval)
        {
            hasUpdated = false;
            return retval;
        }

        /// <summary>
        /// 已重载。从数据库中删除该对象
        /// </summary>
        /// <returns>影响的行数</returns>
        public override Int32 Delete()
        {
            if (!OnDeleting()) return -1;
            return OnDeleted(base.Delete());
        }
        #endregion
        #endregion

        #region 查找
        /// <summary>
        /// 查找
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="startRowIndex"></param>
        /// <param name="maximumRows"></param>
        /// <returns></returns>
        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public static IList<Title> Search(string condition, int startRowIndex, int maximumRows)
        {
            String str = SearchWhere(condition);
            return SelectAll(str, null, null, startRowIndex, maximumRows);
        }

        /// <summary>
        /// 每一个查找方法，都必须对应一个拥有一模一样的参数（名字顺序类型都一致）的Count方法，
        /// 这样页面控件才能使用实体类内部的分页机制。
        /// 因为这两个方法所产生的where条件是一样的，只是最后调用的方法有所不同而已，
        /// 所以可以新增第三个函数用处生成where字句。
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="startRowIndex"></param>
        /// <param name="maximumRows"></param>
        /// <returns></returns>
        public static Int32 SearchCount(string condition, int startRowIndex, int maximumRows)
        {
            String str = SearchWhere(condition);
            return SelectCount(str, null, null, startRowIndex, maximumRows);
        }

        private static String SearchWhere(string condition)
        {
            if (String.IsNullOrEmpty(condition) || String.IsNullOrEmpty(condition.Trim())) return null;

            StringBuilder sb = new StringBuilder();
            sb.Append("1<>1");

            //如果是数字，试试ID
            int k = 0;
            if (int.TryParse(condition, out k)) sb.AppendFormat(" Or {0}={1}", Title._.ID, condition);

            //要把单引号替换成为两个单引号，防止SQL注入
            sb.AppendFormat(" Or {0} like '%{1}%'", _.UserName, condition.Replace("'", "''"));
            sb.AppendFormat(" Or {0} like '%{1}%'", _.TitleName, condition.Replace("'", "''"));
            return sb.ToString();
        }
        #endregion

        #region 扩展属性
        /// <summary>
        /// 本标题对应的文章
        /// </summary>
        public IList<Article> Articles
        {
            get
            {
                return Article.SelectAll(Article._.TitleID, ID);
            }
        }

        private String _Content;
        /// <summary>
        /// 内容
        /// </summary>
        [Description("内容")]
        [DataObjectField(false, false, true, 50000)]
        [BindColumn("", Description = "内容")]
        public String Content
        {
            get
            {
                if (String.IsNullOrEmpty(_Content))
                {
                    IList<Article> list = Articles;
                    if (list == null || list.Count < 1 || String.IsNullOrEmpty(list[0].Content)) return "";
                    StringBuilder sb = new StringBuilder();
                    foreach (Article a in list)
                    {
                        if (!String.IsNullOrEmpty(a.Content)) sb.Append(a.Content);
                    }
                    _Content = sb.ToString();
                }
                return _Content;
            }
            set
            {
                _Content = value;
            }
        }

        /// <summary>
        /// 本标题对应的评论
        /// </summary>
        public IList<Reply> Replys
        {
            get
            {
                return Reply.SelectAll(Reply._.TitleID + "=" + ID, Reply._.PostTime + " Desc", null, 0, 10);
            }
        }

        #endregion

        #region 扩展方法
        #endregion

        #region 查找
        /// <summary>
        /// 根据栏目编号，获取可作为他的所有文章
        /// </summary>
        /// <param name="__ID">栏目编号</param>
        /// <param name="__order">排序</param>
        /// <param name="startRowIndex">起始行，0开始</param>
        /// <param name="maximumRows">最大返回行数</param>
        /// <returns>标题 实体数组</returns>
        [DataObjectMethod(DataObjectMethodType.Select, false)]
        public static IList<Title> SelectAllByBoard(Int32 __ID, String __order, int startRowIndex, int maximumRows)
        {
            String str = SearchWhere(__ID);
            if (String.IsNullOrEmpty(__order)) __order = _.UpdateTime + " Desc";
            return SelectAll(str, __order, null, startRowIndex, maximumRows);
        }

        /// <summary>
        /// 根据栏目编号，获取可作为他的所有文章
        /// </summary>
        /// <param name="__ID">栏目编号</param>
        /// <param name="__order">排序</param>
        /// <param name="startRowIndex">起始行，0开始</param>
        /// <param name="maximumRows">最大返回行数</param>
        /// <returns></returns>
        public static Int32 SelectCountByBoard(Int32 __ID, String __order, int startRowIndex, int maximumRows)
        {
            String str = SearchWhere(__ID);
            if (String.IsNullOrEmpty(__order)) __order = _.UpdateTime + " Desc";
            return SelectCount(str, __order, null, startRowIndex, maximumRows);
        }

        private static String SearchWhere(Int32 __ID)
        {
            String[] ns = new String[] { _.BoardID, _.BoardID2 };
            Object[] vs = new Object[] { __ID, __ID };
            return MakeCondition(typeof(Title), ns, vs, "or");
        }
        #endregion

        #region 首页调用
        /// <summary>
        /// 获取指定版面的标题
        /// </summary>
        /// <param name="boardname">栏目名</param>
        /// <param name="n">条数</param>
        /// <returns></returns>
        public static IList<Title> SelectAllForBoard(String boardname, int n)
        {
            if (String.IsNullOrEmpty(boardname)) return null;
            if (n < 1) n = 10;

            IList<Board> bs = Board.SelectAll(Board._.BoardName, boardname);
            if (bs == null || bs.Count < 1) return null;

            return SelectAllByBoard(bs[0].ID, null, 0, n);
        }

        /// <summary>
        /// 获取指定版面的标题
        /// </summary>
        /// <param name="boardid"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public static IList<Title> SelectAllForBoard(Int32 boardid, int n)
        {
            if (boardid < 1) return SelectAll(null, null, 0, n);
            return SelectAllByBoard(boardid, null, 0, n);
        }

        /// <summary>
        /// 取最热文章
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static IList<Title> SelectTop(int n)
        {
            if (n < 1) n = 10;
            return SelectAll(null, _.Hits + " Desc", null, 0, n);
            //StringBuilder sb = new StringBuilder();
            //sb.Append(_.UpdateTime);
            //sb.Append(">");
            //sb.Append(SqlDataFormat(DateTime.Now.AddDays(-30), typeof(DateTime), typeof(Title)));
            //return SelectAll(OqlToSql(typeof(Title), sb.ToString()), _.Hits + " Desc", null, 0, n);
        }
        #endregion
    }
}